#include <stdio.h>

#include "qwindow.h"
#include "qapplication.h"

#define MAX_WINDOW_HANDLES     128

int QWindow::wndCounter = 0;
QWindow *regwnd[MAX_WINDOW_HANDLES];
int numregwnd = 0;

QWindow::QWindow(const QString& caption, QWidget *parent, const char *name, int wflags)
	: QWidget(parent, name)
{
	mycaption = caption;

	if ((wflags & WFLAG_NOWINDOW) == 0) {
		WNDCLASS wc;
		memset(&wc, 0, sizeof(WNDCLASS));
		wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
		wc.lpfnWndProc = windowProc;
		wc.hInstance = qApp->hInstance;
		wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
		sprintf(wndName, "MainWClass%d", ++wndCounter);
		wc.lpszClassName = wndName;
		wc.lpszMenuName = NULL;
		wc.hCursor = LoadCursor(NULL, IDC_ARROW);
		wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
		if (!RegisterClass(&wc)) {
			fprintf(stderr, "cannot register window\n");
			exit(1);
		}

		hwnd = CreateWindowEx(
		    0,                      // no extended styles
		    wndName,	            // class name
		    caption.c_str(),        // window name
		    WS_OVERLAPPEDWINDOW,    // style
	            CW_USEDEFAULT,          // geometry
	            CW_USEDEFAULT,
	            CW_USEDEFAULT,
	            CW_USEDEFAULT,
		    (HWND)NULL,             // no parent or owner window
		    (HMENU)NULL,            // class menu used
		    qApp->hInstance,  	    // instance handle
		    NULL);                  // no window creation data

		if (hwnd == (HWND)0) {
			fprintf(stderr, "cannot create window\n");
			exit(1);
		}

		registerWindowHandle(hwnd, this);
	}
}

QWindow::~QWindow()
{
	unregisterWindowHandle(hwnd);
}

void QWindow::registerWindowHandle(HWND hwnd, QWindow *w)
{
	for (int i = 0; i < numregwnd; ++i)
		if (!regwnd[i]) {
			regwnd[i] = w;
			return;
		}
        if (numregwnd >= MAX_WINDOW_HANDLES)
                fprintf(stderr, "warning: maximum number of window handles exceed\n");
        else
                regwnd[numregwnd++] = w;
}

void QWindow::unregisterWindowHandle(HWND hwnd)
{
	for (int i = 0; i < numregwnd; ++i)
		if (regwnd[i]->hwnd == hwnd) {
			regwnd[i] = 0;
			break;
		}
}

QWindow *QWindow::findWindowByHandle(HWND hwnd)
{
	for (int i = 0; i < numregwnd; ++i)
		if (regwnd[i] && regwnd[i]->hwnd == hwnd)
			return regwnd[i];
	return 0;
}

void QWindow::show()
{
	ShowWindow(hwnd, SW_SHOW);
}


void QWindow::move(int x, int y)
{
	QWidget::move(x, y);
	MoveWindow(hwnd, x, y, mywidth, myheight, TRUE);
}

void QWindow::resize(int width, int height)
{
	QWidget::resize(width, height);
	MoveWindow(hwnd, myx, myy, width, height, TRUE);
}

void QWindow::setGeometry(int x, int y, int width, int height)
{
	QWidget::setGeometry(x, y, width, height);
	MoveWindow(hwnd, x, y, width, height, TRUE);
}

void QWindow::setCaption(const QString& caption)
{
	QWidget::setCaption(caption);
	SetWindowText(hwnd, caption.c_str());
}

LRESULT CALLBACK QWindow::windowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	QWindow *w = QWindow::findWindowByHandle(hwnd);
	if (w)
		switch (uMsg) {
		case WM_MOVE:
			w->myx = (int)LOWORD(lParam);
			w->myy = (int)HIWORD(lParam);
			printf("window %p \"%s\": new pos %d %d\n", w, w->myname, w->myx, w->myy);
			break;
		case WM_SIZE:
			w->mywidth = (int)LOWORD(lParam);
			w->myheight = (int)HIWORD(lParam);
			printf("window %p \"%s\": new size %d %d\n", w, w->myname, w->mywidth, w->myheight);
			break;
		case WM_DESTROY:
			if (w->isTopLevelWidget())
				PostQuitMessage(0);
			break;
		}
	return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
